"""
Connection 303

	This class will collect and store requests sent to a given host url. Constructor sends HEAD request in order
	to determine whether the url truly exists or not.
	
	Expect 'example.com'

"""

from time import clock

from collections import defaultdict

from httplib import HTTPConnection
from httplib import HTTPResponse
import dns.resolver

from TLD303 import TLDRepo

from threading import Thread, Lock

class OpenDNS():
	location = 'guidetest.a.id.opendns.com'
	server = 'OpenDNS Guide'
	ip = '67.215.65.132'

#class NameServer():
#	
#	repo = defaultdict(list)
#	
#	def keys(self):
#		return self.repo.keys()
#	
#	def 

#Used to act as a timeout response - currently HTTPConnection throws an error, I believe
class DummyResponse():
	
	def __init__(self):
		self.status=408
			
class Connection303():

	def __init__( self, url, tldRepo, connect=False ):
		self.url = url
		self._connected = False
		self._existence = None
		self._TLDRepo = tldRepo
		self._responses = defaultdict()
		self._nameservers = []
		
		if connect: #HTTP HEAD request - (relatively slow)
			self.connect()
	
	def connect( self ):
		if not self._connected:
			self.sendRequest( 'HEAD', '' )
			self._setExistence()
			if self.exists():
				try:
					self._setNS()
				except:
					pass
					
	
	def sendRequest( self, request, path ):
		conn = HTTPConnection( self.url )
		try:
			conn.request( request, path )
			response = conn.getresponse()
		except:
			response = DummyResponse()
		conn.close()
		self._responses[ (request, path) ] = response
	
	def getRequests( self ):
		return self._responses.keys()
		
	def getResponse( self, request, path ):
		try:
			return self._responses[ ( request, path ) ]
		except:
			return None
	
	def exists( self ):
		return self._existence
	
	def getNS( self ):
		return self._nameservers
	
	def _setNS( self ):
		self._nameservers = [ str(r) for r in dns.resolver.query( self._TLDRepo.NSurl(self.url), 'NS' ) ]
	
	def _setExistence( self ):
		headr = self._responses[('HEAD','')] 
		if headr.status >= 400:
			self._existence = False
		elif headr.status == 303 and ( headr.getheader('location') == OpenDNS.location or headr.getheader('server') == OpenDNS.server ):
			self._existence = False
		else:
			self._existence = True
		
	def __str__( self ):
		ex='X'
		status='N/A'
		if self._existence is None:
			ex='-'
		elif self._existence:
			ex='O'
			status=str(self.getResponse('HEAD','').status)
		return '[ ' + self.url + ' | ' + status + ' | ' + ex + ' ]'
		
#	def __repr__( self ):
#		return "[ URL='" + self.url + "', exists='" + str(self._existence) + "', Requests='" + str(self.getRequests) + "' ]"
		
